import Vue from "vue";
const vm = new Vue();

const fnBlockLoading = (() => {
    let loadingMap = new Map();

    return async (fnBlock, loadingOptions = {}) => {
        let {
            target = "fullscreen",
            text,
            spinner,
            background,
            customClass,
        } = loadingOptions;
        let loadingConfig;
        switch (target) {
            case "fullscreen":
                loadingConfig = {
                    fullscreen: true,
                    lock: true,
                    text,
                    spinner,
                    background,
                    customClass,
                };
                break;
            default:
                target =
                    typeof target === "object"
                        ? target
                        : document.querySelector(target);

                loadingConfig = {
                    target,
                    text,
                    spinner,
                    background,
                    customClass,
                };
                break;
        }

        let existNumBefore = loadingMap.get(target) || 0;

        switch (target) {
            case "fullscreen":
                existNumBefore++;
                break;
            default: //阻断模式 不允许连续点击
                if (existNumBefore > 0) {
                    return Promise.reject();
                } else {
                    existNumBefore++;
                }
                break;
        }

        loadingMap.set(target, existNumBefore);

        let loadingInstance = vm.$loading(loadingConfig);

        let result;
        try {
            result = await fnBlock();
        } catch {
            result = Promise.reject();
        }

        await vm.$nextTick();

        let existNumAfter = loadingMap.get(target) || 0;
        existNumAfter--;
        if (existNumAfter < 1) {
            loadingInstance.close();
            loadingMap.delete(target);
        } else {
            loadingMap.set(target, existNumAfter);
        }

        return result;
    };
})();

Vue.prototype.fnBlockLoading = fnBlockLoading;
export default fnBlockLoading;
